package com.laivi.basic.model.file.writer;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import com.laivi.basic.common.constants.Constant;
import com.laivi.basic.model.datastruct.ValueMap;
import com.laivi.basic.module.log.Log;
import com.laivi.basic.module.log.Logs;

public class CsvWriter {
	private final static Log log=Logs.getLog(CsvWriter.class);
	
	private File file;
	private String split=",";
	private BufferedWriter bw;
	private boolean isOpen=false;
	
	public CsvWriter(String path){
		this(new File(path));
	}
	
	public CsvWriter(File file){
		this.file=file;
	}
	
	public void open(){
		try{
			if(!file.exists()) file.createNewFile();
			bw=new BufferedWriter(new FileWriter(file));
			isOpen=true;
		}catch(Exception e){
			log.error(e.getMessage(), e);
		}
	}
	
	public void close(){
		if(isOpen && bw!=null){
			try {
				bw.close();
				isOpen=false;
			} catch (IOException e) {
				log.error(e.getMessage(), e);
			}
		}
	}
	
	public void write(String[] values){
		if(!isOpen) open();
		try {
			bw.write(getLine(values));
			bw.newLine();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
	}
	
	public void write(List<String[]> values){
		if(!isOpen) open();
		try{
			for(String[] value:values){
				bw.write(getLine(value));
				bw.newLine();
			}
		}catch (IOException e) {
			log.error(e.getMessage(), e);
		}finally{
			close();
		}
	}
	
	public void writeMap(List<ValueMap> values){
		if(values!=null&& values.size()>0){
			String[] fields=values.get(0).getKeys();
			writeMap(values,fields,fields);
		}
	}
	
	public void writeMap(List<ValueMap> values,String[] titles,String[] fields){
		if(!isOpen) open();
		try{
			if(values!=null&& values.size()>0){
				bw.write(getLine(titles));
				bw.newLine();
				for(ValueMap value:values){
					bw.write(getLine(value,fields));
					bw.newLine();
				}
			}
		}catch (IOException e) {
			log.error(e.getMessage(), e);
		}finally{
			close();
		}
	}
	
	private String getLine(String[] values){
		StringBuffer sb=new StringBuffer();
		for(String value:values){
			sb.append(value+split);
		}
		if(values==null||values.length==0) return Constant.EMPTY;
		sb=new StringBuffer(sb.substring(0, sb.length()-1));
		return sb.toString();
	}
	
	private String getLine(ValueMap values,String[] fields){
		StringBuffer sb=new StringBuffer();
		for(String field:fields){
			sb.append(String.valueOf(values.get(field))+split);
		}
		if(values==null||values.size()==0) return Constant.EMPTY;
		sb=new StringBuffer(sb.substring(0, sb.length()-1));
		return sb.toString();
	}

	public void setSplit(String split) {
		this.split = split;
	}
}